package com.summer.user.center.service;

import cn.hutool.core.collection.CollUtil;
import com.summer.user.center.mapper.MenuMapper;
import com.summer.user.center.model.MenuItem;
import com.summer.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * Created by likun on 2017/1/17.
 */
@Service
public class MenuServiceImpl implements MenuService {

    @Autowired
    private MenuMapper menuMapper;
    @Autowired
    private RedisUtil redisUtil;

    public final static String RESOURCE_CACHE_PREFIX = "summer:resource:";

    @Override
    public MenuItem findMenuItem() {
        ArrayList<MenuItem> items = menuMapper.findAll();
        MenuItem menu = new MenuItem();
        menu.setName("菜单列表");
        menu.setLvl(-1);
        ArrayList<MenuItem> menuList = new ArrayList<>();
        menu.setChildren(menuList);
        genMenu(items, menuList); //组装树状结构数据
        return menu;
    }

    /**
     * 获取所有的菜单列表
     *
     * @return
     */
    @Override
    public ArrayList<MenuItem> finMenuItemAll() {
        MenuItem menuItem = findMenuItem();
        ArrayList<MenuItem> menuList = new ArrayList<>();
        menu2list(menuItem.getChildren(), menuList);
        return menuList;
    }

    /**
     * 将递归树形菜单读取成list
     *
     * @param children
     * @param menuList
     */
    private void menu2list(ArrayList<MenuItem> children, ArrayList<MenuItem> menuList) {
        if (children != null && children.size() > 0) {
            for (MenuItem item : children) {
                menuList.add(item);
                if (item.getChildren() != null && item.getChildren().size() > 0) {
                    menu2list(item.getChildren(), menuList);
                }
            }
        }
    }

    /**
     * 根据id获取资源
     *
     * @param menuId 菜单id
     * @return
     */
    @Override
    public MenuItem findMenuById(Long menuId) {
        List<MenuItem> menuItemList = menuMapper.findMenuById(menuId);
        if (menuItemList == null || menuItemList.size() == 0) {
            return null;
        }
        return menuItemList.get(0);
    }

    /**
     * 更新菜单资源
     *
     * @param menu
     * @return
     */
    @Override
    public boolean update(MenuItem menu) {
        int i = menuMapper.update(menu);
        redisUtil.deleteKey(RESOURCE_CACHE_PREFIX + "*");
        return i > 0;
    }

    /**
     * 添加菜单
     *
     * @param menu
     * @return
     */
    @Override
    public boolean create(MenuItem menu) {
        //设置菜单等级
        if (menu.getPrentId() != null) {
            List<MenuItem> prentMenu = menuMapper.findMenuById(menu.getPrentId());
            if (prentMenu != null && prentMenu.size() > 0) {
                MenuItem pm = prentMenu.get(0);
                if (pm.getLvl() == null || pm.getLvl().intValue() == 0) {
                    menu.setLvl(1);
                } else {
                    menu.setLvl(pm.getLvl() + 1);
                }
            } else {
                return false;
            }
        }
        long id = menuMapper.create(menu);
        redisUtil.deleteKey(RESOURCE_CACHE_PREFIX + "*");
        return id > 0;
    }

    /**
     * 删除菜单
     *
     * @param id
     * @return
     */
    @Override
    public boolean delete(Long id) {
        MenuItem menuItem = findMenuItem();
        List<Long> ids = new ArrayList<>();
        if (CollUtil.isNotEmpty(menuItem.getChildren())) {
            menuItem.getChildren().forEach(item -> eachMenu(item, ids, id, true));
        }
        int row = 0;
        for (Long i : ids) {
            row += menuMapper.delete(i);
        }
        redisUtil.deleteKey(RESOURCE_CACHE_PREFIX + "*");
        return row > 0;
    }

    @Override
    public MenuItem findUserMenuItem(Long userId) {
        ArrayList<MenuItem> items = menuMapper.findUserMenu(userId);
        MenuItem menu = new MenuItem();
        menu.setName("菜单列表");
        menu.setLvl(-1);
        menu.setType(0);
        ArrayList<MenuItem> menuList = new ArrayList<>();
        menu.setChildren(menuList);
        if (items.size() > 0) {
            //组装树状结构数据
            genMenu(items, menuList);
        }
        return menu;
    }

    private void eachMenu(MenuItem item, List<Long> ids, Long id, boolean equalsId) {
        if (equalsId) {
            if (item.getId() != null && id.equals(item.getId())) {
                ids.add(item.getId());
                if (CollUtil.isNotEmpty(item.getChildren())) {
                    item.getChildren().forEach(i -> eachMenu(i, ids, id, false));
                }
            } else {
                if (CollUtil.isNotEmpty(item.getChildren())) {
                    item.getChildren().forEach(i -> eachMenu(i, ids, id, true));
                }
            }
        } else {
            ids.add(item.getId());
            if (CollUtil.isNotEmpty(item.getChildren())) {
                item.getChildren().forEach(i -> eachMenu(i, ids, id, equalsId));
            }
        }

    }


    /**
     * 组装树状结构数据
     *
     * @param items
     * @param menuList
     */
    private void genMenu(ArrayList<MenuItem> items, ArrayList<MenuItem> menuList) {
        Map<Long, MenuItem> menuItemMap = new HashMap<>();
        items.forEach(menuItem -> menuItemMap.put(menuItem.getId(), menuItem));
        items.forEach(menuItem -> {
            if (menuItem.getPrentId() != null) {
                MenuItem pMenu = menuItemMap.get(menuItem.getPrentId());
                if (pMenu != null) {
                    ArrayList<MenuItem> children = pMenu.getChildren();
                    if (children == null) {
                        children = new ArrayList<>();
                        pMenu.setChildren(children);
                    }
                    children.add(menuItem);
                }
            }
        });
        for (MenuItem item : items) {
            if (item.getPrentId() == null) {
                menuList.add(item);
                break;
            }
        }
    }
}
